<template>
  <div class="mid-top-container">
    <span class="title">航空器构型</span>
    <div class="model" ref="containerVc"></div>
  </div>
</template>

<script setup lang="ts">
import {nextTick, onMounted, ref} from "vue";
import {
  AmbientLight,
  AxesHelper,
  Color, DirectionalLight, GridHelper,
  PerspectiveCamera,
  Scene,
  WebGLRenderer
} from "three";
//@ts-ignore
import {OrbitControls} from "three/examples/jsm/controls/OrbitControls";
//@ts-ignore
import {FBXLoader} from "three/examples/jsm/loaders/FBXLoader";

let containerVc = ref<HTMLDivElement>();
let camera: PerspectiveCamera;
let scene: Scene;
let renderer: WebGLRenderer;
let controls: OrbitControls;
//容器宽高
let divWidth = ref<number>();
let divHeight = ref<number>();


/**
 * 初始化相机
 */
function initCamera() {
  camera = new PerspectiveCamera(45, (divWidth.value as number) / (divHeight.value as number), 0.1, 2000);
  camera.position.set(-30, 40, 30);
  camera.lookAt(scene.position)
}

/**
 * 初始化场景
 */
function initScene() {
  scene = new Scene();
  scene.background = new Color(0x000000);

  //添加网格
  let grid = new GridHelper(100, 30, 0xffffff, 0x808080);
  scene.add(grid);

  //添加一个坐标系
  let axes = new AxesHelper(30)
  scene.add(axes)

}

/**
 * 渲染器
 */
function initRenderer() {
  renderer = new WebGLRenderer({antialias: true});
  renderer.setSize(divWidth.value as number, divHeight.value as number);
  renderer.setClearColor(new Color(0xeeeeee))
  containerVc.value?.appendChild(renderer.domElement)//将渲染出来的东西挂载到Dom结点上
}

/**
 * 窗口尺寸改变的回调
 */
function onWindowResize() {
  camera.aspect = (divWidth.value as number) / (divHeight.value as number);
  camera.updateProjectionMatrix()
  renderer.setSize(divWidth.value as number, divHeight.value as number);
  renderScene();
}

/**
 * 鼠标控制
 */
function initControls() {
  controls = new OrbitControls(camera, renderer.domElement);
  controls.addEventListener('change', () => renderer);
  controls.target.set(0, 2, 0);
  controls.update();
  window.addEventListener('resize', onWindowResize)
}

//递归渲染
function renderScene() {
  requestAnimationFrame(renderScene)
  renderer.render(scene, camera);
}

/**
 * 加载模型
 */
function loaderModel() {
  let loader = new FBXLoader();
  loader.load('models/747_high.fbx', (obj: any) => {

    //设置Transform
    obj.position.set(0, 5, 0);
    obj.scale.set(1, 1, 1);

    scene.add(obj)
  })
}

/**
 * 初始化灯光
 */
function initLight() {
  //平行光
  let Dirlight = new DirectionalLight(0xffffff, 2.0);
  Dirlight.position.set(0, 10, 0);
  Dirlight.castShadow = true
  scene.add(Dirlight)
  //环境光
  let ambientLight = new AmbientLight(0xffffff, 0.5);
  scene.add(ambientLight)
}

function init() {
  initScene();
  initLight();
  initCamera();
  loaderModel();
  initRenderer();
  initControls();
  //计算容器宽高
  divWidth.value = containerVc.value?.offsetWidth;
  divHeight.value = containerVc.value?.offsetHeight;
}

async function initAfterSizeReady() {
  await nextTick();
  divWidth.value = containerVc.value?.offsetWidth || window.innerWidth;
  divHeight.value = containerVc.value?.offsetHeight || window.innerHeight;
  init();
  renderScene();
}

onMounted(() => {
  initAfterSizeReady();
});


</script>

<style scoped lang="scss">
.mid-top-container {
  height: 100%;
  width: 100%;
  //background-color: #93efc2;

  .title {
    padding-top: 5px;
    font-size: 30px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: white;
    margin-bottom: 10px;
  }

  .model {
    padding: 5px;
    width: 100%;
    height: 100%;
  }
}

</style>